package com.topnav.mc.admin.controller;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.js.lib.annotation.ApiLogger;
import com.js.lib.cache.SysCache;
import com.js.lib.result.Result;
import com.topnav.mc.admin.bean.OrgDeviceBean;
import com.topnav.mc.admin.dao.mapper.DeviceChannelMapper;
import com.topnav.mc.admin.dao.mapper.DeviceMapper;
import com.topnav.mc.admin.entity.DeviceChannel;
import com.topnav.mc.admin.entity.Organization;
import com.topnav.mc.admin.entity.bean.DeviceBean;
import com.topnav.mc.admin.entity.param.DeviceParam;
import com.topnav.mc.admin.entity.wrapper.DeviceWrapper;
import com.topnav.mc.admin.security.PermissionGrade;
import com.topnav.mc.admin.service.IOrganizationService;
import com.topnav.mc.admin.service.impl.DeviceTreeServiceImpl;
import com.topnav.mc.base.mc.McController;
import com.topnav.mc.position.PositionUtil;
import com.topnav.mc.uitls.MapUtil;
import com.topnav.mc.uitls.PermissionGradeUtil;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import com.topnav.mc.admin.entity.Device;
import com.topnav.mc.admin.service.IDeviceService;

import javax.annotation.Resource;
import java.util.*;

@Api(value = "admin/device", tags = "设备管理")
@RestController
@CrossOrigin
@RequestMapping("admin/device")
//public class DeviceController extends CurdController<Device, IDeviceService> {
public class DeviceController extends McController<Device, DeviceBean, DeviceParam,IDeviceService, DeviceWrapper>{
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private IOrganizationService organizationService;
    @Autowired
    private IDeviceService deviceService;
    @Resource
    private PermissionGradeUtil pmGradeUtil;
    @Autowired
    private DeviceChannelMapper deviceChannelMapper;

    @Resource
    private DeviceTreeServiceImpl deviceSearchService;
    @Autowired
    private SysCache sysCache;
    @Autowired
    private PositionUtil positionUtil;




    /**
     * 根据用户输入的值查询4G执法仪，上级带机构的
     * 给前端 Tree组件使用
     * */
/*    @ApiLogger(apiName="/search4GDevicesByValue")
    @ApiOperation(value = "根据输入值查询4G执法仪")
    @ApiImplicitParams(
            {@ApiImplicitParam(name="value", value = "输入值", required=false,dataTypeClass = String.class)})
    @PostMapping("/search4GDevicesByValue")
    @ResponseBody
    public Result search4GDevicesByValue(@RequestBody Map<String,Object> param) {

        return search4GDevicesByValue1(param);
    }*/


    /**
     * 根据输入值搜索
     * @param param
     * @return
     */
    /*private Result search4GDevicesByValue1(Map<String,Object> param){
        Map<String,Double> center = MapUtil.getCenterPoint();

        *//** 搜索出所有设备 *//*
        List<OrgDeviceBean> orgDevices = new ArrayList<OrgDeviceBean>();
        List<OrgDeviceVo> devices = deviceMapper.searchByValue(param);
        List<OrgDeviceBean> children=null;
        for(OrgDeviceVo d : devices){
            children = getFromChildren(orgDevices,d.getOrgPath());
            OrgDeviceBean b=new OrgDeviceBean()
                    .setId(d.getId().toString())
                    .setTitle(d.getName()) //+("1".equals(d.getOnline())?"->在线":"->离线"))
                    .setType("dev")
                    .setLongitude(center.get("longitude"))
                    .setLatitude(center.get("latitude"))
                    .setDisabled(false)
                    .setOnline(d.getOnline())
                    .setDeviceType(d.getType());//1、 普能执法仪，2、4G执法仪, 3、监控摄像头
            b.getArrt().put("channel",d.getDefaultChannel());
            b.getArrt().put("gbServerId",d.getGbServerId());
            b.getArrt().put("code",d.getCode());
            children.add(b);
        }
        return Result.ok(orgDevices);
    }*/

    @ApiLogger(apiName="/get/begin/code/{prefix}")
    @ApiOperation(value = "根据输入的前辍查询起始编号，批量注册使用")
    @ApiImplicitParams(
            {@ApiImplicitParam(name="prefix", value = "前辍", required=true,dataTypeClass = String.class)})
    @GetMapping("/get/begin/code/{prefix}")
    @ResponseBody
    public Result getBeginCode(@PathVariable String prefix){
        //最大编号的那一条
        QueryWrapper<Device> wrapper = new QueryWrapper<>();
        wrapper.likeRight("code",prefix);
        wrapper.and(wrapper1 -> wrapper1.eq("cate",2).or().eq("cate",3));
        wrapper.orderByDesc("code");
        Device device = deviceService.getOne(wrapper,false);
        Integer index = 1;
        if (device != null){
           index = Integer.valueOf(device.getCode().substring(14,20));
           index ++;
        }
        return Result.ok(index);
    }

    /**
     * 批量注册
     * @param param
     * {
     *  beginNum:1,
     *  num:1,
     *  beginCode:null,
     *  endCode:null,
     *  codePrefix:null,
     *}
     * @return
     */
    @ApiLogger(apiName="/batch/save")
    @ApiOperation(value = "批量注册")
    @PostMapping("/batch/save")
    @ResponseBody
    public Result batchSave(@RequestBody Map<String,Object> param){
        if (param.get("num")==null){return Result.error("<注册数量>必须提供");}
        if (param.get("codePrefix")==null){return Result.error("参数<codePrefix>必须提供");}
        if (param.get("gbServerId")==null){return Result.error("<国标服务器> 必须提供");}
        if (param.get("beginNum")==null){return Result.error("<开始编号> 必须提供");}
        if (param.get("cate")==null){return Result.error("参数<cate> 必须提供");}
        if (param.get("type")==null){return Result.error("参数<type> 必须提供");}
        Integer num = Integer.valueOf(param.get("num").toString());
        String codePrefix = String.valueOf(param.get("codePrefix").toString());
        Long  gbServerId = Long.valueOf(param.get("gbServerId").toString());
        Integer beginNum = Integer.valueOf(param.get("beginNum").toString());
        Integer type = Integer.valueOf(param.get("type").toString());
        Integer cate = Integer.valueOf(param.get("cate").toString());
        Long orgId=null;
        if (param.get("orgId")!=null){orgId=Long.valueOf(param.get("orgId").toString());}

        String code=null;
        Device device=null;
        int total=0;
        int addcount=0;
        for(int i=beginNum;i<beginNum+num;i++ ){
            code = String.valueOf(i);
            while (code.length() < 6){code="0"+code;}
            code = codePrefix + code;
            device = new Device().setCode(code).setCate(cate).setType(type).setName(code).setOrgId(orgId)
                    .setGbServerId(gbServerId).setDefaultChannel(code).setDefaultAlarmChannel(code)
                    .setState(1).setSubscriberPosition(0).setOnline(false);
            device.setCreateTime(new Date()).setUpdateTime(new Date());

            total ++;
            if (deviceService.save(device)){
                addcount ++;
            }
        }

        JSONObject json = new JSONObject();
        json.put("total",total);
        json.put("ok",addcount);
        json.put("failure",total-addcount);

        return Result.ok(json);
    }


    /**
     *  由path做为参数取得上级单位
     * @param list
     * @param path
     * @return
     */

    private List<OrgDeviceBean> getFromChildren(List<OrgDeviceBean> list, String path){
        if (StringUtils.isEmpty(path)){
            for(OrgDeviceBean o: list){
                if (o.getId().equals(-1L)){
                    return o.getChildren();
                }
            }
            OrgDeviceBean b=new OrgDeviceBean().setId("-1").setTitle("未设置机构").setType("org").setDisabled(true);
            b.setChildren(new ArrayList<OrgDeviceBean>());
            list.add(b);
            return b.getChildren();
        }

        String ids[] = path.split("/");
        for(int i=0;i<ids.length;i++) {
            list = getFromChildren(list,Long.valueOf(ids[i]));
            if (i==ids.length-1) {
                return list;
            }
        }
        return list;
    }
    /**
     * 由id为参数传入
     * 在 children查找，没有则创建
     * @param list
     * @param id
     * @return
     */
    private List<OrgDeviceBean> getFromChildren(List<OrgDeviceBean> list, Long id){
        for(OrgDeviceBean o: list){
            if (id.equals(o.getId())){
                return o.getChildren();
            }
        }
        Organization o = organizationService.getById(id);
        OrgDeviceBean b=new OrgDeviceBean().setId(o.getId().toString()).setTitle(o.getShortName()).setType("org").setDisabled(true);
        b.setChildren(new ArrayList<OrgDeviceBean>());
        list.add(b);
        return b.getChildren();
    }



    /**
     * 统计每个单位的设备数
     * @param permissionGrade 权限控制
     * @param param 输入的参数
     * @param multiChannelDevices 有多个通道的设备
     * @return
     */
    private Map<Object,String> count(
            PermissionGrade permissionGrade,
            Map<String,Object> param,
            List<Device> multiChannelDevices){
        Map<Object,Integer> allMap = null;//this.deviceCount(permissionGrade,param,multiChannelDevices);
        Map<Object,Integer> onlineMap = this.onlineCount(permissionGrade,param,multiChannelDevices);

        String value = null;
        Map<Object,String> resultMap = new HashMap<>();
        for(Map.Entry<Object, Integer> e : allMap.entrySet()){
            if (onlineMap.get(e.getKey()) == null){
                value = "(0/" + e.getValue() + ")";
            }else{
                value = "(" + onlineMap.get(e.getKey())+"/" + e.getValue() + ")";
            }
            resultMap.put(e.getKey(), value);
        }

        return resultMap;
    }





    /**
     * 统计每个单位的在线设备数
     * @param permissionGrade 权限控制
     * @param param 输入的参数
     * @param multiChannelDevices 有多个通道的设备
     * @return
     */
    private Map<Object,Integer> onlineCount(
            PermissionGrade permissionGrade,
            Map<String,Object> param,
            List<Device> multiChannelDevices){
        Map<Object,Integer> onLineMap = new HashMap<>();
        List<String> devCodeArray = new ArrayList<>();

        QueryWrapper<DeviceChannel> wrapper = new QueryWrapper();
        if (permissionGrade!=null){
            if (permissionGrade.getPermissionLevel()==3 || permissionGrade.getPermissionLevel() == 4){
                wrapper.likeRight("o.path",permissionGrade.getOrgPath());
            }else if (permissionGrade.getPermissionLevel()==2){
                wrapper.eq("d.org_id",permissionGrade.getOrgId());
            }else if (permissionGrade.getPermissionLevel()==1){
                wrapper.eq("d.user_id",permissionGrade.getUserId());
            }
        }
        wrapper.eq("status",1);
        wrapper.isNotNull("d.org_id");
        //结果集 orgId,deviceId,total,projCateId,orgCode,path
        List<Map<String,Object>> channelCounts = null;//deviceChannelMapper.countByOrgAndDevice(wrapper);

        //onLineMap =  this.sum(channelCounts,multiChannelDevices);

        System.err.println(onLineMap);
        return onLineMap;
    }


    /**
     * 设备固件升级
     * @param device
     * @return
     */
    @ApiLogger(apiName="/firmware/updgrade")
    @ApiOperation(value = "固件升级")
    @PostMapping("/firmware/updgrade")
    @ResponseBody
    public Result firmwareUpdgrade(@RequestBody Device device){
        return deviceService.firmwareUpdgrade(device);
    }


}
